#ifndef _SCHEDULER_H_
#define _SCHEDULER_H_
#include <pin.H>
#include <map>

#include "../HSGlobal.h"
#include "../PowerModels/PowerModel.h"
#include "../Stash/Stash.h"
#include "OperationInfo.h"

class Scheduler{

  protected:
 
    void updateTicks( long *ticks, long fullTickCost, PowerModel::QueryResult *res );

  public:

    Scheduler(PowerModel *, Stash *nv);
    static const double tickLengthSeconds;// = 1e-9;
    // 200 MHz processor -- 5 ns/cycle
    static const unsigned long ticksPerCycle = 5;
    unsigned long cycleTicks;
    unsigned long deadTicks;
    unsigned long currentTick;
    unsigned long currentCycle;
    bool deadLastTick;
    map<unsigned,unsigned long> deathsByTryBlock;

    PowerModel *powerModel;
    Stash *NV;
    bool FailureBit;
    unsigned deathID;
    
    
    void dumpStats(FILE *f);
    unsigned long insCost( INT32 insType );
    unsigned long readCost( ADDRINT inst, ADDRINT opea);
    unsigned long writeCost( ADDRINT inst, ADDRINT opea);
    void scheduleInstruction( ADDRINT inst, unsigned long cycles );
    void scheduleInstruction( OperationInfo *oi);

    /*Below is the interface that gets exposed to the runtime.*/
    void STORE_NV(void *value, unsigned long NVAddr, size_t size);
  
    void LOAD_NV(void *buf, unsigned long NVAddr, size_t size);
  
    void LD_CURR_CP_AFTER_RECOVERY_RTN( void *recoveryRtn );
   
    void GET_RECOVERY_ROUTINE( void *recoveryRtn ); 
  
    unsigned long GET_DEATH_ID();
  
    void SET_DEATH_ID(unsigned long id);
  
    bool GET_FAILURE_BIT();
    
    void SET_FAILURE_BIT(); 
    
    void CLEAR_FAILURE_BIT(); 
  
    void STORE_EXPLICIT_CHECKPOINT( unsigned ckptNo, unsigned long size );
  
    void LOAD_EXPLICIT_CHECKPOINT( unsigned ckptNo, unsigned long size );
  
    void LOAD_CURRENT_CHECKPOINT();

};
#endif
